#pragma once

#include "common.h"

// http://www.faqs.org/rfcs/rfc1982.html

// Sequence Number 0 - (2^31 - 1)

// seqcmp: compare two seq#, considering the wraping
// seqlen: length from the 1st to the 2nd seq#, including both
// seqoff: offset from the 2nd to the 1st seq#
// incseq: increase the seq# by 1
// decseq: decrease the seq# by 1
// incseq: increase the seq# by a given offset

class NtdSeq
{
public:
	inline static const int seqcmp(const int32& seq1, const int32& seq2)
	{return (abs(seq1 - seq2) < m_iSeqNoTH) ? (seq1 - seq2) : (seq2 - seq1);}

	inline static const int seqlen(const int32& seq1, const int32& seq2)
	{return (seq1 <= seq2) ? (seq2 - seq1 + 1) : (seq2 - seq1 + m_iMaxSeqNo + 2);}

	inline static const int seqoff(const int32& seq1, const int32& seq2)
	{
		if (abs(seq1 - seq2) < m_iSeqNoTH)
			return seq2 - seq1;

		if (seq1 < seq2)
			return seq2 - seq1 - m_iMaxSeqNo - 1;

		return seq2 - seq1 + m_iMaxSeqNo + 1;
	}

	inline static const int32 incseq(const int32 seq)
	{return (seq == m_iMaxSeqNo) ? 0 : seq + 1;}

	inline static const int32 decseq(const int32& seq)
	{return (seq == 0) ? m_iMaxSeqNo : seq - 1;}

	inline static const int32 incseq(const int32& seq, const int32& inc)
	{return (m_iMaxSeqNo - seq >= inc) ? seq + inc : seq - m_iMaxSeqNo + inc - 1;}

public:
	static const int32 m_iSeqNoTH;             // threshold for comparing seq. no.
	static const int32 m_iMaxSeqNo;            // maximum sequence number
};